-----
-- Division by base 4, precompute d*1 (no need), d*2(no need), d*3
--
-- Unsigned divider
-- 
-- 
-- 
-----
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity div_base_4 is
	PORT (
	clk : in STD_LOGIC;
	start_division : in STD_LOGIC;
	numerator : in STD_LOGIC_VECTOR(31 downto 0);
	denominator : in STD_LOGIC_VECTOR(31 downto 0);
	
	quotient : out STD_LOGIC_VECTOR (31 downto 0);
	remainder : out STD_LOGIC_VECTOR (31 downto 0)
	);
end div_base_4;

architecture Behavioral of div_base_4 is

	component div_base_4_precompute_layer is
		PORT (
		clk : in STD_LOGIC;
		denominator : in STD_LOGIC_VECTOR(31 downto 0);
		
		out3_main : out STD_LOGIC_VECTOR(31 downto 0);
		out3_overflow : out STD_LOGIC
		);
	end component;
	
	component div_base_4_subtraction_layer is
		PORT(
		denominator : in STD_LOGIC_VECTOR(31 downto 0);
		mult3_overflow : in STD_LOGIC;
		mult3_result : in STD_LOGIC_VECTOR(31 downto 0);
		old_partial_remainder : in STD_LOGIC_VECTOR(31 downto 0);
		
		quotient_digit : out STD_LOGIC_VECTOR(1 downto 0);
		new_partial_remainder : out STD_LOGIC_VECTOR(31 downto 0)
		);
	end component;
	
	component div_base_4_latch_layer is
		PORT(
		clk : in STD_LOGIC; 
		start : in STD_LOGIC;
		
		numerator : in STD_LOGIC_VECTOR(31 downto 0);
		new_partial_remainder : in STD_LOGIC_VECTOR(31 downto 0);
		quotient_digit : in STD_LOGIC_VECTOR(1 downto 0);
		
		output : out STD_LOGIC_VECTOR(63 downto 0)
		);
	end component;
	
	signal mult3_store : STD_LOGIC_VECTOR(31 downto 0);
	signal mult3_overflow : STD_LOGIC;
	
	signal new_quotient_digit : STD_LOGIC_VECTOR(1 downto 0);
	signal new_partial_remainder : STD_LOGIC_VECTOR(31 downto 0);
	
	signal div_output : STD_LOGIC_VECTOR(63 downto 0);
	
begin
	
	precomputer : div_base_4_precompute_layer
	PORT MAP (
	clk => clk,
	denominator => denominator,
	out3_main => mult3_store,
	out3_overflow => mult3_overflow
	);
	
	subtracter : div_base_4_subtraction_layer
	PORT MAP(
	denominator => denominator,
	mult3_overflow => mult3_overflow,
	mult3_result => mult3_store,
	old_partial_remainder => div_output(61 downto 30),
	
	quotient_digit => new_quotient_digit,
	new_partial_remainder => new_partial_remainder
	);
	
	latch_and_control : div_base_4_latch_layer
	PORT MAP(
	clk => clk, 
	start => start_division,
	
	numerator => numerator,
	new_partial_remainder => new_partial_remainder,
	quotient_digit => new_quotient_digit,
	
	output => div_output
	);
	
	quotient <= div_output(31 downto 0);
	remainder <= div_output(63 downto 32);
	
end Behavioral;

